package com.roads.project.service.impl;

import com.roads.common.constant.Constants;
import com.roads.common.constant.UserConstants;
import com.roads.common.exception.ServiceException;
import com.roads.common.utils.DateUtils;
import com.roads.common.utils.StringUtils;
import com.roads.project.domain.ProBoq;
import com.roads.project.domain.ProCompany;
import com.roads.project.domain.ProInstitution;
import com.roads.project.domain.ProInstitutionDetail;
import com.roads.project.mapper.ProCompanyMapper;
import com.roads.project.mapper.ProInstitutionDetailMapper;
import com.roads.project.mapper.ProInstitutionMapper;
import com.roads.project.mapper.ProInstitutionUserMapper;
import com.roads.project.service.IProBoqService;
import com.roads.project.service.IProInstitutionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 机构Service业务层处理
 * 
 * @author nhp
 * @date 2021-11-16
 */
@Service
public class ProInstitutionServiceImpl implements IProInstitutionService {

    @Autowired
    private ProInstitutionMapper proInstitutionMapper;

    @Autowired
    private ProInstitutionDetailMapper detailMapper;

    @Autowired
    private ProInstitutionUserMapper institutionUserMapper;

    /**
     * 查询机构
     * 
     * @param institutionId 机构主键
     * @return 机构
     */
    @Override
    public ProInstitution selectProInstitutionByInstitutionId(Integer institutionId) {
        return proInstitutionMapper.selectProInstitutionByInstitutionId(institutionId);
    }

    @Override
    public ProInstitution getModelByInnerCode(String code) {
        return proInstitutionMapper.getModelByInnerCode(code);
    }

    /**
     * 根据编码查询详细信息
     *
     * @param code 机构编码
     * @return 详细机构
     */
    @Override
    public ProInstitutionDetail getDetailModelByInnerCode(String code) {
        return detailMapper.getModelByInnerCode(code);
    }

    /**
     * 查询项目下机构数量
     *
     * @param projectId 项目ID
     * @return 数量
     */
    @Override
    public int countByProjectId(Integer projectId) {
        return proInstitutionMapper.countByProjectId(projectId);
    }

    /**
     * 查询机构列表
     * 
     * @param proInstitution 机构
     * @return 机构
     */
    @Override
    public List<ProInstitution> selectProInstitutionList(ProInstitution proInstitution) {
        return proInstitutionMapper.selectProInstitutionList(proInstitution);
    }

    /**
     * 查询全部机构列表
     *
     * @param proInstitution 机构
     * @return 机构集合
     */
    @Override
    public List<ProInstitution> selectProInstitutionListAll(ProInstitution proInstitution) {
        return proInstitutionMapper.selectProInstitutionListAll(proInstitution);
    }

    /**
     * 查看项目下所有标段类型机构
     *
     * @param projectId 项目ID
     * @return 标段机构集合
     */
    @Override
    public List<ProInstitution> dropDownBidByProjectId(Integer projectId) {
        return proInstitutionMapper.dropDownBidByProjectId(projectId);
    }

    /**
     * 查询项目下所有驻地类型机构
     *
     * @param projectId 项目ID
     * @return 驻地机构集合
     */
    @Override
    public List<ProInstitution> dropDownZdBidByProjectId(Integer projectId) {
        return proInstitutionMapper.dropDownZdBidByProjectId(projectId);
    }

    /**
     * 查询项目下所有监理类型机构
     *
     * @param projectId 项目ID
     * @return 监理机构集合
     */
    @Override
    public List<ProInstitution> dropDownJlBidByProjectId(Integer projectId) {
        return proInstitutionMapper.dropDownJlBidByProjectId(projectId);
    }

    /**
     * 查询项目下所有总监类型机构
     *
     * @param projectId 项目ID
     * @return 总监机构集合
     */
    @Override
    public List<ProInstitution> dropDownZjBidByProjectId(Integer projectId) {
        return proInstitutionMapper.dropDownZjBidByProjectId(projectId);
    }

    /**
     * 查询项目下所有代建类型机构
     *
     * @param projectId 项目ID
     * @return 代建机构集合
     */
    @Override
    public List<ProInstitution> dropDownDjBidByProjectId(Integer projectId) {
        return proInstitutionMapper.dropDownDjBidByProjectId(projectId);
    }

    /**
     * 查询项目下所有业主类型机构
     *
     * @param projectId 项目ID
     * @return 业主机构集合
     */
    @Override
    public List<ProInstitution> dropDownYzBidByProjectId(Integer projectId) {
        return proInstitutionMapper.dropDownYzBidByProjectId(projectId);
    }

    /**
     * 根据项目ID查询所有标段和分部机构
     *
     * @param projectId 项目ID
     * @return 结果
     */
    @Override
    public List<ProInstitution> selectBidListByProjectId(Integer projectId) {
        return proInstitutionMapper.selectBidListByProjectId(projectId);
    }

    /**
     * 根据用户查询项目下所有标段和分部机构
     *
     * @param projectId 项目ID
     * @param user 用户
     * @return 结果
     */
    @Override
    public List<ProInstitution> selectBidListByUserAndProjectId(Integer projectId, String user) {
        return proInstitutionMapper.selectBidListByUserAndProjectId(projectId, user);
    }

    /**
     * 校验机构编码是否唯一
     *
     * @param proInstitution 机构
     * @return 结果
     */
    @Override
    public String checkInstitutionCodeUnique(ProInstitution proInstitution) {
        Integer institutionId = StringUtils.isNull(proInstitution.getInstitutionId()) ? -1 : proInstitution.getInstitutionId();
        ProInstitution search = proInstitutionMapper.checkInstitutionCodeUnique(proInstitution.getInstitutionCode());
        if (StringUtils.isNotNull(search) && !search.getInstitutionId().equals(institutionId)) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    /**
     * 新增机构
     * 
     * @param proInstitution 机构
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertProInstitution(ProInstitution proInstitution) {
        setCompanyName(proInstitution);
        proInstitution.setCreateTime(DateUtils.getNowDate());
        proInstitutionMapper.insertProInstitution(proInstitution);
        // 机构详情表添加记录
        ProInstitutionDetail detail = new ProInstitutionDetail();
        detail.setInstitutionId(proInstitution.getInstitutionId());
        detail.setInstitutionCode(proInstitution.getInstitutionCode());
        detail.setInstitutionName(proInstitution.getInstitutionName());
        detail.setInnerCode(proInstitution.getInnerCode());
        detail.setCreateBy(proInstitution.getCreateBy());
        detail.setCreateTime(proInstitution.getCreateTime());
        detailMapper.insert(detail);
        // 1.添加监理类型的机构，需要在监理模板里添加默认数据 2.新增计量人员
        if (Constants.INSTITUTION_TYPE_SUPERVISOR.contains(proInstitution.getInstitutionType())) {
            proInstitutionMapper.insertSupervisorBoqTemplate(proInstitution.getInnerCode(), proInstitution.getCreateBy());
            if (StringUtils.isNotEmpty(proInstitution.getMeterageUser())) {
                institutionUserMapper.insert(proInstitution.getInnerCode(), proInstitution.getMeterageUser());
            }
        }
        // 添加代建类型的机构，需要在代建模板里添加默认数据 2.新增计量人员
        if (Constants.INSTITUTION_TYPE_A.equals(proInstitution.getInstitutionType())) {
            proInstitutionMapper.insertAgencyBoqTemplate(proInstitution.getInnerCode(), proInstitution.getCreateBy());
            if (StringUtils.isNotEmpty(proInstitution.getMeterageUser())) {
                institutionUserMapper.insert(proInstitution.getInnerCode(), proInstitution.getMeterageUser());
            }
        }
        return 1;
    }

    /**
     * 修改机构
     * 
     * @param proInstitution 机构
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateProInstitution(ProInstitution proInstitution) {
        ProInstitutionDetail detail = detailMapper.getModelById(proInstitution.getInstitutionId());
        detail.setInstitutionCode(proInstitution.getInstitutionCode());
        detail.setInstitutionName(proInstitution.getInstitutionName());
        detail.setInnerCode(proInstitution.getInnerCode());
        detail.setUpdateBy(proInstitution.getUpdateBy());
        detail.setUpdateTime(DateUtils.getNowDate());
        detailMapper.update(detail);
        proInstitution.setUpdateTime(DateUtils.getNowDate());
        setCompanyName(proInstitution);
        // 计量人员处理
        ProInstitution old = proInstitutionMapper.selectProInstitutionByInstitutionId(proInstitution.getInstitutionId());
        if (StringUtils.isNotEmpty(old.getMeterageUser())
                && StringUtils.isNotEmpty(proInstitution.getMeterageUser())
                && !old.getMeterageUser().equals(proInstitution.getMeterageUser())) {
            // 计量人员发生变化
            if (StringUtils.isNotEmpty(old.getMeterageUser())) {
                institutionUserMapper.delete(old.getInnerCode(), old.getMeterageUser());
            }
            institutionUserMapper.insert(proInstitution.getInnerCode(), proInstitution.getMeterageUser());
        }
        proInstitutionMapper.updateProInstitution(proInstitution);
        return 1;
    }

    private void setCompanyName(ProInstitution proInstitution) {
        // 承包商名称
        if (!StringUtils.isEmpty(proInstitution.getParentCode())) {
            ProInstitution bid = proInstitutionMapper.getModelByInnerCode(proInstitution.getParentCode());
            proInstitution.setBdName(bid.getCompanyName());
        }
        // 驻地
        if (!StringUtils.isEmpty(proInstitution.getZdCode())) {
            ProInstitution zdBid = proInstitutionMapper.getModelByInnerCode(proInstitution.getZdCode());
            proInstitution.setZdName(zdBid.getCompanyName());
        }
        // 监理
        if (!StringUtils.isEmpty(proInstitution.getJlCode())) {
            ProInstitution jlBid = proInstitutionMapper.getModelByInnerCode(proInstitution.getJlCode());
            proInstitution.setJlName(jlBid.getCompanyName());
        }
        // 总监
        if (!StringUtils.isEmpty(proInstitution.getZjCode())) {
            ProInstitution zjBid = proInstitutionMapper.getModelByInnerCode(proInstitution.getZjCode());
            proInstitution.setZjName(zjBid.getCompanyName());
        }
        // 代建
        if (!StringUtils.isEmpty(proInstitution.getDjCode())) {
            ProInstitution djBid = proInstitutionMapper.getModelByInnerCode(proInstitution.getDjCode());
            proInstitution.setDjName(djBid.getCompanyName());
        }
        // 业主
        if (!StringUtils.isEmpty(proInstitution.getYzCode())) {
            ProInstitution yzBid = proInstitutionMapper.getModelByInnerCode(proInstitution.getYzCode());
            proInstitution.setYzName(yzBid.getCompanyName());
        }
    }

    /**
     * 批量删除机构
     * 
     * @param institutionIds 需要删除的机构主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteProInstitutionByInstitutionIds(Integer[] institutionIds) {
        for (Integer institutionId : institutionIds) {
            ProInstitution institution = proInstitutionMapper.selectProInstitutionByInstitutionId(institutionId);
            // 施工标段-- 标段，分包
            if (Constants.INSTITUTION_TYPE_CONSTRUCTION.contains(institution.getInstitutionType())) {
                deleteConstruction(institution.getInnerCode());
            }
            // 监理标段-- 驻地，监理，总监
            if (Constants.INSTITUTION_TYPE_SUPERVISOR.contains(institution.getInstitutionType())) {
                deleteSupervisor(institution.getInnerCode());
            }
            // 代建标段
            if (Constants.INSTITUTION_TYPE_A.equals(institution.getInstitutionType())) {
                deleteAgency(institution.getInnerCode());
            }
            // 删除标段、标段详情、标段用户
            institutionUserMapper.deleteByCode(institution.getInnerCode());
            detailMapper.delete(institutionId);
            proInstitutionMapper.deleteProInstitutionByInstitutionId(institutionId);
        }
        return 1;
    }

    /**
     * 删除施工标段
     *
     * @param institutionCode 标段编号
     */
    private void deleteConstruction(String institutionCode) {
        // 查看施工机构是否计量，如果计量则无法进行机构删除
        int meterageCount = proInstitutionMapper.hasMeterageConstruction(institutionCode);
        if (meterageCount > 0) {
            throw new ServiceException(String.format("%1$s已计量,不能删除", institutionCode));
        }
        // 查看施工机构是否有变更，如果有变更无法进行机构删除
        int changeCount = proInstitutionMapper.hasChangeOrder(institutionCode);
        if (changeCount > 0) {
            throw new ServiceException(String.format("%1$s有变更令,不能删除", institutionCode));
        }
        proInstitutionMapper.deleteConstruction(institutionCode);
    }

    /**
     * 删除监理标段
     *
     * @param institutionCode 标段编号
     */
    private void deleteSupervisor(String institutionCode) {
        // 查看监理机构是否计量，如果计量则无法进行机构删除
        int meterageCount = proInstitutionMapper.hasMeterageSupervisor(institutionCode);
        if (meterageCount > 0) {
            throw new ServiceException(String.format("%1$s已计量,不能删除", institutionCode));
        }
        proInstitutionMapper.deleteSupervisor(institutionCode);
    }

    /**
     * 删除代建标段
     *
     * @param institutionCode 标段编号
     */
    private void deleteAgency(String institutionCode) {
        // 查看监理机构是否计量，如果计量则无法进行机构删除
        int meterageCount = proInstitutionMapper.hasMeterageAgency(institutionCode);
        if (meterageCount > 0) {
            throw new ServiceException(String.format("%1$s已计量,不能删除", institutionCode));
        }
        proInstitutionMapper.deleteAgency(institutionCode);
    }

    /**
     * 删除机构信息
     * 
     * @param institutionId 机构主键
     * @return 结果
     */
    @Override
    public int deleteProInstitutionByInstitutionId(Integer institutionId) {
        return proInstitutionMapper.deleteProInstitutionByInstitutionId(institutionId);
    }

    /**
     * 根据ID获取标段详情
     *
     * @param institutionId 标段ID
     * @return 标段详情
     */
    @Override
    public ProInstitutionDetail getInstitutionDetailById(Integer institutionId) {
        return detailMapper.getModelById(institutionId);
    }

    /**
     * 修改标段详情
     *
     * @param detail 标段详情
     * @return 结果
     */
    @Override
    public int updateInstitutionDetail(ProInstitutionDetail detail) {
        return detailMapper.update(detail);
    }

}
